package com.zzh.lib.recorder;

import android.media.AudioFormat;
import android.media.MediaRecorder;
import android.os.Build;

import com.zzh.lib.recorder.def.OnExceptionCallback;
import com.zzh.lib.recorder.def.OnRecorderCallback;
import com.zzh.lib.recorder.def.OnRecorderProcessListener;
import com.zzh.lib.recorder.def.OnStateChangeCallback;
import com.zzh.lib.recorder.mp3.PCMFormat;


public class HMediaRecorderParams {
    public static final HMediaRecorderParams DEFAULT = new HMediaRecorderParams();


    private int audioSource;
    private int outputFormat;
    private int audioEncoder;
    private int mAudioChannels = 1;
    private int mAudioEncodingBitRate = 64000;
    private int mAudioSamplingRate = 44100;
    private boolean save2File = false, fileFormatWave = false;
    private int bufferSize = 0;
    /**
     * 降噪
     */
    private boolean denoise = false;
    private OnMaxAmplitudeListener mOnMaxAmplitudeListener;

    private String fileSaveDir;

    private OnRecorderProcessListener mOnRecorderProcessListener;


    /**
     * 自定义属性
     */
    private OnRecorderCallback mOnRecorderCallback;

    private OnStateChangeCallback mOnStateChangeCallback;
    private OnExceptionCallback mOnExceptionCallback;

    public HMediaRecorderParams() {
        setAudioSource(MediaRecorder.AudioSource.MIC);
        setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

        if (Build.VERSION.SDK_INT > 28) {
            setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
        } else {
            setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        }
    }

    public int getBufferSize() {
        return bufferSize;
    }

    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }

    public OnRecorderProcessListener getOnRecorderProcessListener() {
        return mOnRecorderProcessListener;
    }

    public HMediaRecorderParams setOnRecorderProcessListener(OnRecorderProcessListener onRecorderProcessListener) {
        mOnRecorderProcessListener = onRecorderProcessListener;
        return this;
    }

    public int getAudioSource() {
        return audioSource;
    }

    /**
     * 设置音频数据源
     *
     * @param audioSource {@link MediaRecorder.AudioSource}
     * @return
     */
    public HMediaRecorderParams setAudioSource(int audioSource) {
        this.audioSource = audioSource;
        return this;
    }

    public int getOutputFormat() {
        return outputFormat;
    }

    /**
     * 设置输出格式
     *
     * @param outputFormat {@link MediaRecorder.OutputFormat}
     * @return
     */
    public HMediaRecorderParams setOutputFormat(int outputFormat) {
        this.outputFormat = outputFormat;
        return this;
    }

    public int getAudioEncoder() {
        return audioEncoder;
    }

    public int getAudioChannels() {
        return mAudioChannels;
    }

    /**
     * 设置编码格式
     *
     * @param audioEncoder {@link MediaRecorder.AudioEncoder}
     * @return
     */
    public HMediaRecorderParams setAudioEncoder(int audioEncoder) {
        this.audioEncoder = audioEncoder;
        return this;
    }

    public HMediaRecorderParams setAudioChannels(int audioChannels) {
        mAudioChannels = audioChannels;
        return this;
    }

    public boolean isSave2File() {
        return save2File;
    }

    public HMediaRecorderParams setSave2File(boolean save2File) {
        this.save2File = save2File;
        return this;
    }

    public boolean isFileFormatWave() {
        return fileFormatWave;
    }

    /**
     * 设置文件保存格式，true 保存成wave文件，false 保存为pcm文件
     *
     * @param fileFormatWave true 保存成wave文件，false 保存为pcm文件
     * @return HMediaRecorderParams 返回当前对象
     */
    public HMediaRecorderParams setFileFormatWave(boolean fileFormatWave) {
        this.fileFormatWave = fileFormatWave;
        return this;
    }

    public int getAudioEncodingBitRate() {
        return mAudioEncodingBitRate;
    }

    public HMediaRecorderParams setAudioEncodingBitRate(int audioEncodingBitRate) {
        mAudioEncodingBitRate = audioEncodingBitRate;
        return this;
    }

    public int getAudioSamplingRate() {
        return mAudioSamplingRate;
    }

    public HMediaRecorderParams setAudioSamplingRate(int audioSamplingRate) {
        mAudioSamplingRate = audioSamplingRate;
        return this;
    }

    public OnMaxAmplitudeListener getOnMaxAmplitudeListener() {
        return mOnMaxAmplitudeListener;
    }

    public HMediaRecorderParams setOnMaxAmplitudeListener(OnMaxAmplitudeListener onMaxAmplitudeListener) {
        mOnMaxAmplitudeListener = onMaxAmplitudeListener;
        return this;
    }

    public interface OnMaxAmplitudeListener {
        void onMaxAmplitude(double amp);
    }

    public OnRecorderCallback getOnRecorderCallback() {
        return mOnRecorderCallback;
    }

    public HMediaRecorderParams setOnRecorderCallback(OnRecorderCallback onRecorderCallback) {
        mOnRecorderCallback = onRecorderCallback;
        return this;
    }

    public OnStateChangeCallback getOnStateChangeCallback() {
        return mOnStateChangeCallback;
    }

    public HMediaRecorderParams setOnStateChangeCallback(OnStateChangeCallback onStateChangeCallback) {
        mOnStateChangeCallback = onStateChangeCallback;
        return this;
    }

    public OnExceptionCallback getOnExceptionCallback() {
        return mOnExceptionCallback;
    }

    public HMediaRecorderParams setOnExceptionCallback(OnExceptionCallback onExceptionCallback) {
        mOnExceptionCallback = onExceptionCallback;
        return this;
    }

    public String getFileSaveDir() {
        return fileSaveDir == null ? "" : fileSaveDir;
    }

    public HMediaRecorderParams setFileSaveDir(String fileSaveDir) {
        this.fileSaveDir = fileSaveDir;
        return this;
    }

    public boolean isDenoise() {
        return denoise;
    }

    public HMediaRecorderParams setDenoise(boolean denoise) {
        this.denoise = denoise;
        return this;
    }

    public static HMediaRecorderParams buildDefaultPCM() {
        HMediaRecorderParams params = new HMediaRecorderParams()
                .setAudioChannels(AudioFormat.CHANNEL_IN_MONO)
                .setDenoise(true)
                .setOutputFormat(PCMFormat.PCM_16BIT.getAudioFormat());
        params.setAudioSamplingRate(44100);
        params.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
        params.setBufferSize(-1);
        return params;
    }
}
